const router = require('koa-router')()
var jwt = require('jsonwebtoken') //引入token
const User = require('../model/userSchema')
const Role = require('../model/roleSchema')
const Menu = require('../model/menusSchema')
const Counter = require('../model/counterSchema')
const utils = require('../utils/utils')
const svgCaptcha = require('svg-captcha');
const excel = require("./../utils/excel")//引入excel
router.prefix('/users')
//列表渲染 get 上传 POST 修改PUT或者POST 删除delete或者POST   RESTFUL风格语法
//如果是POST请求 获取前端发送的参数 ctx.request.body
//如果是GET请求 获取前端发送的参数 ctx.request.query
// {userPwd:0}作为返回条件·0代表不返回·1代表返回·{}或者nu11代表全部返回 'userName state mobile role roleList'代表挑选返回
//登录接口
router.post('/login', async (ctx, next) => {
  // 1. 从请求体中解构出用户名和密码
  var { userName, userPwd, captcha } = ctx.request.body
  try {
    // 2. 在数据库中查找匹配的用户
    // - 只返回指定字段：userName, state, mobile, role, roleList  //findOne返回一条数据
    let res = await User.findOne({ userName, userPwd }, 'userName state mobile role roleList userEmail')
    // 3. 如果用户存在
    if (res && captcha.toLowerCase() == ctx.session.picCode.toLowerCase()) {
      // 4. 获取Mongoose文档的纯JS对象
      let data = res._doc
      // 5. 生成JWT令牌
      // - 使用用户数据作为payload
      // - 使用'lee'作为密钥（生产环境应使用环境变量）
      // - 设置过期时间为1小时
      let token = jwt.sign({
        data: res
      }, 'lee', { expiresIn: '1h' })
      // 6. 将token添加到返回数据中
      data.token = token
      // console.log('data', data);

      // 7. 返回成功响应（假设utils.success是自定义的成功响应格式）
      ctx.body = utils.success({ data: res, msg: '登录成功', code: 200 })
    }
  } catch (err) {
    ctx.body = utils.success({ data: '账号验证码错误', msg: 'fail' })
  }
})

//用户列表渲染
router.get('/list', async (ctx) => {
  var { userId, userName, state, type } = ctx.request.query
  // console.log('ctx.request.query', ctx.request.query);
  var { page, skipIndex } = utils.pager(ctx.request.query)
  try {
    let params = {}
    if (userId) params.userId = userId
    if (userName) params.userName = userName
    if (state && state != 0) params.state = state
    // find返回所有的数据
    const query = User.find(params)
    // limit返回指定数量的数据，skip跳过指定数量的数据
    const list = await query.skip(skipIndex).limit(page.pagesize)
    //countDocuments返回符合条件的总数
    const total = await User.countDocuments(params)
    // 7. 返回成功响应（假设utils.success是自定义的成功响应格式）
    ctx.body = utils.success({ list, total })
    if (type == 'dept') {
      if (state && state != 0) {
        params.state = state
        let res = await User.find(params)
        ctx.body = utils.success(res)
      } else {
        ctx.body = utils.fail('参数错误')
      }
    }
  } catch (err) {
    console.log(err);
  }
})

//权限
router.get('/permissionlist', async (ctx) => {
  const authorization = ctx.request.headers.authorization
  let data = utils.decoded(authorization)
  // console.log('data',data);
  try {
    let menuList = await getMenuList(data.data.role, data.data.roleList)//第一个参数是角色（普通用户还是管理员） 第二个参数角色列表（你是什么职位 如:人事主管 技术总监）
    let actionList = getActionList(JSON.parse(JSON.stringify(menuList)))
    ctx.body = utils.success({ data: { menuList, actionList }, msg: 'ok', code: 200 })
  } catch (err) {
    console.log(err);
  }
})

//按钮的权限
function getActionList(menuList) {
  let actionList = [];

  const deep = (arr) => {
    for (let item of arr) {
      // 如果是按钮/操作类型 (menuType === 2)，并且有menuCode，则添加到actionList
      if (item.menuType === 2 && item.menuCode) {
        actionList.push(item.menuCode);
      }

      // 如果有子菜单，递归处理
      if (item.children && item.children.length > 0) {
        deep(item.children);
      }
    }
  };

  deep(menuList);
  return actionList;
}

//菜单的权限
async function getMenuList(userRole, roleKeys) {
  let rootList = []
  if (userRole == 0) {//管理员
    rootList = await Menu.find({}).lean() || {}
  } else {
    let roleList = await Role.find({ _id: { $in: roleKeys } })
    // console.log(roleList);

    let permissionList = []
    roleList.map(role => {
      let { checkKeys, halfCheckedKeys } = role.permissionList
      permissionList = permissionList.concat([...checkKeys, ...halfCheckedKeys])
    })
    permissionList = [...new Set(permissionList)]
    rootList = await Menu.find({ _id: { $in: permissionList } }).lean()
  }
  return utils.TreeMenuList(rootList)
}



//用户列表新增和编辑
router.post('/operate', async (ctx) => {
  var { userId, userName, userEmail, mobile, job, state, roleList, deptId, active } = ctx.request.body
  // console.log('operate11111', userName, userEmail, mobile, job, state, roleList, deptId, active);
  try {
    if (active == 'add') {
      if (userEmail || mobile) {
        ctx.body = utils.fail('参数错误')
      }
      let res = await User.findOne({ $or: [{ userEmail }, { mobile }] })
      if (res) {
        ctx.body = utils.fail('邮箱或手机号已存在')
        return
      }
      let doc = await Counter.findOneAndUpdate({ _id: 'userId' }, { $inc: { squence_value: 1 } }, { new: true })
      let userRes = new User({
        userId: doc.squence_value,
        userPwd: "123456",
        userName,
        userEmail,
        mobile,
        role: 1,
        job,
        state: 1,
        roleList,
        deptId
      })
      await userRes.save()
      //给前端返回的数据，可以让前端正常运行
      ctx.body = utils.success('新增成功')
    } else {
      let res = await User.findOneAndUpdate({ userId }, { userName, userEmail, mobile, job, state, roleList, deptId })
      ctx.body = utils.success('更新成功')
    }
  } catch (err) {
    console.log(err);
  }
})

//用户删除
router.post('/delete', async (ctx) => {
  var { userIds } = ctx.request.body
  try {
    let { modifiedCount } = await User.updateMany({ userId: { $in: userIds } }, { state: 2 })
    ctx.body = utils.success(`成功删除了${modifiedCount}条数据`)
  } catch (err) {
    console.log(err);
  }
})


//用户恢复
router.post('/update', async (ctx) => {
  var { userIds } = ctx.request.body
  try {
    let { modifiedCount } = await User.updateMany({ userId: { $in: userIds } }, { state: 1 })
    ctx.body = utils.success(`成功恢复了${modifiedCount}条数据`)
  } catch (err) {
    console.log(err);
  }
})


//验证码接口
router.get('/captcha', async (ctx) => {
  var cap = svgCaptcha.create({
    size: 4, // 验证码长度
    width: 120, //验证码的宽度
    height: 40, //验证码的高度
    fontSize: 45, //验证码的字体大小
    ignoreChars: "0oO1ilI", // 验证码字符中排除 0o1i
    noise: 2, // 干扰线条的数量
    color: true, // 验证码的字符是否有颜色，默认没有，如果设定了背景，则默认有
    background: "#ddd", // 验证码图片背景颜色
  });
  let img = new Buffer.from(cap.data).toString("base64");
  let base64Img = "data:image/svg+xml;base64," + img;
  let text = cap.text.toLowerCase()
  // console.log('text', text);
  // console.log('base64Img', base64Img);
  ctx.session.picCode = text
  ctx.body = utils.success({ code: 200, data: { imgurl: `${base64Img}` }, msg: 'ok' })
})

//导出excel数据
router.post('/excel', async (ctx) => {
    // 使用sequelize拿到数据库数据
    let res = await User.find({}, { _id: 0, userPwd: 0 })
    console.log(res);
    const res2 = JSON.parse(JSON.stringify(res))
    // 将数据转换为Buffer
    let buffer = excel.exportExcel(res2)
    console.log('buffer', buffer);
    // 设置content-type请求头
    // ctx.set('Content-Type', 'application/vnd.openxmlformats');
    // // 设置文件名信息请求头
    // ctx.set('Content-Disposition', "attachment; filename=" + encodeURIComponent("文件名") + ".xlsx");
    // // 文件名信息由后端返回时必须设置该请求头,否则前端拿不到Content-Disposition响应头信息
    // ctx.set("Access-Control-Expose-Headers", "Content-Disposition")
    // 将buffer返回给前端
    ctx.body = utils.success(buffer)
});


module.exports = router
